import 'dart:convert';

import 'package:im_app/im/socket/SignalWebSocket.dart';

import '../socket/dto/base/Resp.dart';
import '../socket/dto/business/Login.dart';
import '../socket/dto/business/PullData.dart';
import '../socket/dto/business/WebRtcData.dart';
import 'RpcSignalService.dart';
import 'SignalSession.dart';
import 'dto.dart';
import '../util/LoggerUtil.dart';

class SignalService {

  final _logger = createLogger();
  final SignalSession _signalSession;
  final SignalWebSocket _signalWebSocket;

  SignalService(this._signalSession, this._signalWebSocket);

  Future<LoginResp> login(userId, token, tenantCode) async {
    var loginReq = WebRtcLoginReq(userId: userId, authToken: token, tenantCode: tenantCode,
        terminalType: TerminalType.android.name);

    var rpcLoginService = RpcSignalService(_signalWebSocket);
    _logger.i("[signal loginReq]");
    var loginResp = await rpcLoginService.login(loginReq, 60);
    _logger.i("[signal loginResp], resp: ${jsonEncode(loginResp)}");

    _signalSession.loginSuccess(loginResp.userId!, loginResp.authCode, loginResp.token, loginResp
        .authToken, loginResp.tenantCode, loginResp.serverDateTime);;

    return loginResp;
  }

  Future<LoginResp> reconnection() async {
    var tenantCode = _signalSession.getData("TENANT_CODE") as String;
    var authToken = _signalSession.getData("authToken") as String;
    var userId = _signalSession.userId;
    var reconnection = WebRtcLoginReq(userId: userId!, authToken: authToken!, tenantCode: tenantCode!,
        terminalType: TerminalType.android.name);

    var rpcLoginService = RpcSignalService(_signalWebSocket);

    var loginResp = await rpcLoginService.login(reconnection, 60);
    _logger.i("[signal loginResp], resp: ${jsonEncode(loginResp)}");

    _signalSession.loginSuccess2(loginResp);
    return loginResp;
  }

  Future<OkResp> createRoom(ChatType chatType, TerminalType terminalType, double screenWidth, double screenHeight) async {
    var createRoomReq = WebRtcCreateRoomReq(chatType: chatType, terminalType: terminalType, width: screenWidth,
        height: screenHeight);

    var rpcSignalService = RpcSignalService(_signalWebSocket);

    var resp = await rpcSignalService.createRoom(createRoomReq, 60);
    _logger.i("[signal createRoomResp], resp: ${jsonEncode(resp)}");
    return resp;
  }

  Future<WebRtcRoomInfo> joinRoom(String roomName, TerminalType terminalType, double width, double height) async {
    var createRoomReq = WebRtcJoinRoomReq(terminalType: terminalType, width: width, height: height, roomName: roomName);

    var rpcSignalService = RpcSignalService(_signalWebSocket);

    var resp = await rpcSignalService.joinRoom(createRoomReq, 60);
    _logger.i("[signal joinRoomResp], resp: ${jsonEncode(resp)}");
    return resp;
  }

  Future<OkResp> exitRoom(String roomName) async {
    var exitRoomReq = WebRtcExitRoomReq(roomName: roomName);

    var rpcSignalService = RpcSignalService(_signalWebSocket);

    var resp = await rpcSignalService.exitRoom(exitRoomReq, 60);
    _logger.i("[signal exitRoomResp], resp: ${jsonEncode(resp)}");
    return resp;
  }

  Future<OkResp> sendSdp(String roomName, String remoteUserId, String sdp, SdpType sdpType) async {
    var tenantCode = _signalSession.getData("TENANT_CODE") ;
    var userId = _signalSession.userId;

    var sdpReq = WebRtcP2pSdpReq(toUserId: remoteUserId, sdp: sdp, sdpType: sdpType, roomName: roomName);

    var rpcSignalService = RpcSignalService(_signalWebSocket);

    _logger.i("[signal sendSdpReq]");
    var resp = await rpcSignalService.sdp(sdpReq, 60);
    _logger.i("[signal sendSdpResp], result: ${resp.coder}: ${resp.otherInfo}");
    return resp;
  }

  Future<OkResp> iceCandidate(String roomName, String toUserId, IceCandidate iceCandidate) async {
    var candidateReq = WebRtcP2pCandidateReq(roomName: roomName, toUserId: toUserId, iceCandidate: iceCandidate);

    _logger.i("[signal iceCandidateReq], toUserId: $toUserId");
    var rpcSignalService = RpcSignalService(_signalWebSocket);

    var resp = await rpcSignalService.iceCandidate(candidateReq, 60);
    _logger.i("[signal iceCandidateResp]");
    return resp;
  }

}